import { createContext, useContext, useEffect } from "react";
import { useOutlet, useLocation, matchPath } from "react-router-dom";
import type { FC, PropsWithChildren, ReactNode } from "react";

// 定义 KeepAliveLayoutProps
interface KeepAliveLayoutProps extends PropsWithChildren {
	keepPaths: Array<string | RegExp>;
	keepElements?: Record<string, ReactNode>;
	dropByPath?: (path: string) => void;
}

// 定义上下文类型
type KeepAliveContextType = Omit<Required<KeepAliveLayoutProps>, "children">;

// 初始化缓存的页面元素
const keepElements: KeepAliveContextType["keepElements"] = {};

// 创建 KeepAlive 上下文
export const KeepAliveContext = createContext<KeepAliveContextType>({
	keepPaths: ['/keep-alive/about', '/keep-alive/mine'],
	keepElements,
	dropByPath(path: string) {
		keepElements[path] = null;
	},
});

// 检查是否匹配 keepPaths
const isKeepPath = (keepPaths: Array<string | RegExp>, path: string) => {
	let isKeep = false;
	for (let i = 0; i < keepPaths.length; i++) {
		let item = keepPaths[i];
		console.log(`Checking if ${path} matches ${item}`); // 打印调试信息
		if (item === path) {
			isKeep = true;
		}
		if (item instanceof RegExp && item.test(path)) {
			isKeep = true;
		}
		if (typeof item === "string" && item.toLowerCase() === path) {
			isKeep = true;
		}
	}
	return isKeep;
};

// 自定义 Hook，用于管理页面的 keepAlive
export function useKeepOutlet() {
	const location = useLocation();
	const element = useOutlet();

	const { keepElements, keepPaths } = useContext(KeepAliveContext);
	// 确保 keepPaths 在 useKeepOutlet 中正确获取
	useEffect(() => {
		console.log("keepPaths in useKeepOutlet", keepPaths);
	}, [keepPaths]);

	const isKeep = isKeepPath(keepPaths, location.pathname);

	if (isKeep) {
		keepElements![location.pathname] = element;
	}

	return (
		<>
			{Object.entries(keepElements).map(([pathname, element]) => (
				<div
					key={pathname}
					style={{
						height: "100%",
						width: "100%",
						position: "relative",
						overflow: "hidden auto",
					}}
					className="keep-alive-page"
					hidden={!matchPath(location.pathname, pathname)}
				>
					{element}
				</div>
			))}
			{!isKeep && element}
		</>
	);
}

const KeepAliveLayout: FC<KeepAliveLayoutProps> = (props) => {
	const { keepPaths } = props;
	const keepElements: KeepAliveContextType["keepElements"] = {};
	const dropByPath = (path: string) => {
		keepElements[path] = null;
	};

	console.log("keepPaths in KeepAliveLayout", keepPaths);

	return (
		<KeepAliveContext.Provider
			value={{ keepPaths, keepElements, dropByPath }}
		>
			{useKeepOutlet()}
		</KeepAliveContext.Provider>
	);
};

export default KeepAliveLayout;
